package com.hockeo.client.ui.widgets;

import java.util.ArrayList;
import java.util.List;

import com.extjs.gxt.ui.client.data.BaseTreeLoader;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.data.ModelIconProvider;
import com.extjs.gxt.ui.client.data.ModelStringProvider;
import com.extjs.gxt.ui.client.data.RpcProxy;
import com.extjs.gxt.ui.client.data.TreeLoader;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.TreePanelEvent;
import com.extjs.gxt.ui.client.store.TreeStore;
import com.extjs.gxt.ui.client.util.IconHelper;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.treepanel.TreePanel;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AbstractImagePrototype;
import com.hockeo.client.VHMain;
import com.hockeo.client.model.JSData;
import com.hockeo.client.model.JSSimpleData;
import com.hockeo.client.res.AppConstants;
import com.hockeo.client.ui.panels.DataEditor;

/**
 * Tree representing the VH main menu.
 *
 * @version $Id$
 * @author jjanke
 */
public class MainMenuTree extends LayoutContainer
{
  private TreePanel<JSData> d_tree;
  private TreeStore<JSData> d_store;

  @Override
  protected void onRender( Element parent, int index )
  {
    super.onRender( parent, index );
    setLayout( new FitLayout() );

    // RPC proxy
    //
    RpcProxy<List<JSData>> proxy = new RpcProxy<List<JSData>>() {
      @Override
      protected void load( Object objModel, AsyncCallback<List<JSData>> callback )
      {
        JSData model = (JSData) objModel;

        if ( model == null )
          callback.onSuccess( getFirstLevelNodes() );
        else
          callback.onSuccess( getChildren( model ) );
      }
    };

    // tree loader
    //
    TreeLoader<JSData> loader = new BaseTreeLoader<JSData>( proxy ) {
      @Override
      public boolean hasChildren( JSData data )
      {
        return data.hasChildren() || data.hasRemoteChildren();
      }
    };

    d_store = new TreeStore<JSData>( loader );

    // tree
    //
    d_tree = new TreePanel<JSData>( d_store );

    // labels
    //
    d_tree.setLabelProvider( new ModelStringProvider<JSData>() {
      public String getStringValue( JSData model, String property )
      {
        if ( model instanceof JSData )
          return ( (JSSimpleData) model ).getLabel();
        else
          return "TODO"; // TODO
      }
    } );

    // icons
    //
    d_tree.setIconProvider( new ModelIconProvider<JSData>() {
      public AbstractImagePrototype getIcon( JSData model )
      {
        if ( model instanceof JSSimpleData )
          return ( (JSSimpleData) model ).getIcon();
        else
          return IconHelper.create( "images/nav/" + model.getId() + "_16.png", 16, 16 ); // TODO
      }
    } );

    // react to double-click events
    //
    d_tree.addListener( Events.OnDoubleClick, new Listener<TreePanelEvent<JSData>>() {
      @SuppressWarnings( "synthetic-access" )
      public void handleEvent( TreePanelEvent<JSData> evt )
      {
        JSData data = (JSData) evt.getNode().getModel();

        if ( data.getId().equals( "dataEditor" ) )
          VHMain.get().setCenterContent( DataEditor.get() );
        else
          Window.alert( "Node '" + data.getId() + "' not (yet) handled." );
      }
    } );

    add( d_tree );
  }

  /**
   * Returns the top level entries of the main menu.
   */
  protected List<JSData> getFirstLevelNodes()
  {
    final List<JSData> list = new ArrayList<JSData>();
    final AppConstants consts = VHMain.getAppConstants();
    JSSimpleData data;

    data = new JSSimpleData( "office", consts.menuOffice(), VHMain.ICON_OFFICE );
    list.add( data );

    data = new JSSimpleData( "countries", consts.menuCountries(), VHMain.ICON_COUNTRIES );
    list.add( data );

    return list;
  }

  /**
   * Enables the admin node on the menu (by default, it is not shown).
   */
  public void enableAdminNode()
  {
    if ( d_store == null )
      return;

    final AppConstants consts = VHMain.getAppConstants();

    JSSimpleData miAdmin = new JSSimpleData( "admin", consts.menuAdminSettings(), VHMain.ICON_SETTINGS );
    miAdmin.add( new JSSimpleData( "dataEditor", consts.menuDataEditor(), VHMain.ICON_BULLET_BLUE ) );

    d_store.add( miAdmin, true );
  }

  private List<JSData> getChildren( JSData parent )
  {
    final List<JSData> list = new ArrayList<JSData>();

    // add local children
    //
    for( ModelData model : parent.getChildren() )
      list.add( (JSData) model );

    // add possibly existing remote children
    //
    if ( parent.hasRemoteChildren() )
      ; // TODO

    return list;
  }


}
